package com.dc.util;


import com.dc.common.DateUtil;
import io.netty.buffer.ByteBuf;
import org.springframework.util.FileCopyUtils;

import java.io.*;
import java.nio.ByteBuffer;


public class InstructUtils {

    public static void main(String[] args) {
        String start = DateUtil.getStartTime("start");
        String s = start.replaceAll("-", " ").replaceAll(":", " ");//用String的替换功能
        String[] timeString = s.split(" ");

        int year = stringToInt(timeString[0]);
        //年 2018 十六进制  7 E2   byte[] {7,-30 }
        int month = stringToInt(timeString[1]);
        int day = stringToInt(timeString[2]);
        int hour = stringToInt(timeString[3]);
        int minute = stringToInt(timeString[4]);
        int second = stringToInt(timeString[5]);
        byte[] today = {(byte) year, (byte) month, (byte) day, (byte) hour, (byte) minute, (byte) second};
        for (byte b : today) {
            System.out.println("二进制:" + Integer.toBinaryString((b & 0xFF) + 0x100).substring(1));
            int i = scale2Decimal(Integer.toBinaryString((b & 0xFF) + 0x100).substring(1), 2);
            System.out.println(i);
        }
    }

    public static int stringToInt(String s) {
        return Integer.parseInt(s);
    }
    /**
     * 二进制转十进制
     *
     * @param number
     * @return
     */
    public static int binary2Decimal(String number) {
        return scale2Decimal(number, 2);
    }

    /**
     * 其他进制转十进制
     *
     * @param number
     * @return
     */
    public static int scale2Decimal(String number, int scale) {
        checkNumber(number);
        if (2 > scale || scale > 32) {
            throw new IllegalArgumentException("scale is not in range");
        }
        // 不同其他进制转十进制,修改这里即可
        int total = 0;
        String[] ch = number.split("");
        int chLength = ch.length;
        for (int i = 0; i < chLength; i++) {
            total += Integer.valueOf(ch[i]) * Math.pow(scale, chLength - 1 - i);
        }
        return total;

    }


    public static void checkNumber(String number) {
        String regexp = "^\\d+$";
        if (null == number || !number.matches(regexp)) {
            throw new IllegalArgumentException("input is not a number");
        }
    }

    /**
     * 截取byte数组并转成2进制拼接一起
     *
     * @param arr
     * @return byte[]
     */
    public static String getByteIntercept(byte[] arr, int starIndex, int endIndex) {
        byte[] data = new byte[endIndex - starIndex + 1];
        System.arraycopy(arr, starIndex, data, 0, data.length);
        String result = "";
        for (byte b : data) {
            result += Integer.toBinaryString((b & 0xFF) + 0x100).substring(1);
        }
        return result;
    }

    /**
     * 浮点转换为字节
     *
     * @param f
     * @return
     */
    public static byte[] float2byte(float f) {

        // 把float转换为byte[]
        int fbit = Float.floatToIntBits(f);

        byte[] b = new byte[4];
        for (int i = 0; i < 4; i++) {
            b[i] = (byte) (fbit >> (24 - i * 8));
        }

        // 翻转数组
        int len = b.length;
        // 建立一个与源数组元素类型相同的数组
        byte[] dest = new byte[len];
        // 为了防止修改源数组，将源数组拷贝一份副本
        System.arraycopy(b, 0, dest, 0, len);
        byte temp;
        // 将顺位第i个与倒数第i个交换
        for (int i = 0; i < len / 2; ++i) {
            temp = dest[i];
            dest[i] = dest[len - i - 1];
            dest[len - i - 1] = temp;
        }

        return dest;

    }

    /**
     * 字节转换为浮点
     *
     * @param b     字节（至少4个字节）
     * @param index 开始位置
     * @return
     */
    public static float byte2float(byte[] b, int index) {
        int l;
        l = b[index + 0];
        l &= 0xff;
        l |= ((long) b[index + 1] << 8);
        l &= 0xffff;
        l |= ((long) b[index + 2] << 16);
        l &= 0xffffff;
        l |= ((long) b[index + 3] << 24);
        return Float.intBitsToFloat(l);
    }


    public static void putMassage_cz(byte[] c, String no, int cj, int d, int sj) {
        ByteBuf byteBuf = null;
        byteBuf.writeByte(cj)
                .writeByte(03)
                .writeShort(d)
                .writeShort(sj);
        byte[] ss = CRC.getCRC6(byteBuf.array());
        byteBuf.writeByte(ss[0])
                .writeByte(ss[1]);
    }


    public static String putint(byte[] ss, int i) {
        return ByteUtil.covert(String.valueOf(ss[i] & 0xFF)) + "" + ByteUtil.covert(String.valueOf(ss[i + 1] & 0xFF));
    }

    /**
     * 字节数组转16进制
     *
     * @param bytes 需要转换的byte数组
     * @return 转换后的Hex字符串
     */
    public static String bytesToHex(byte[] bytes) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < bytes.length; i++) {
            String hex = Integer.toHexString(bytes[i] & 0xFF);
            if (hex.length() < 2) {
                sb.append(0);
            }
            sb.append(hex);
            sb.append(" ");
        }
        return sb.toString();
    }

    /**
     * 将指定byte数组以16进制的形式打印到控制台
     *
     * @param hint String
     * @param b    byte[]
     * @return void
     */
    public static void printHexString(String hint, byte[] b) {
        System.out.print(hint);
        for (int i = 0; i < b.length; i++) {
            String hex = Integer.toHexString(b[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            System.out.print(hex.toUpperCase() + " ");
        }
        System.out.println("");
    }

    /**
     * @param b byte[]
     * @return String
     */
    public String Bytes2HexString(byte[] b) {
        String ret = "";
        for (int i = 0; i < b.length; i++) {
            String hex = Integer.toHexString(b[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            ret += " 0x" + hex.toUpperCase();
        }
        return ret;
    }

    /**
     * @param b byte
     * @return String
     */
    public String ByteString(byte b) {
        String ret = "";
        if (b < 10) {
            ret += " 0x0" + b;
        } else {
            ret += " 0x" + b;
        }

        return ret;
    }

    /**
     * 将两个ASCII字符合成一个字节； 如："EF"–> 0xEF
     *
     * @param src0 byte
     * @param src1 byte
     * @return byte
     */
    public byte uniteBytes(byte src0, byte src1) {
        byte _b0 = Byte.decode("0x" + new String(new byte[]{src0})).byteValue();
        _b0 = (byte) (_b0 << 4);
        byte _b1 = Byte.decode("0x" + new String(new byte[]{src1})).byteValue();
        byte ret = (byte) (_b0 ^ _b1);
        return ret;
    }

    /**
     * 将指定字符串src，以每两个字符分割转换为16进制形式 如："2B44EFD9" –> byte[]{0x2B, 0×44, 0xEF,
     * 0xD9}
     *
     * @param src String
     * @return byte[]
     */
    public byte[] HexString2Bytes(String src) {
        if (null == src || 0 == src.length()) {
            return null;
        }
        byte[] ret = new byte[src.length() / 2];
        byte[] tmp = src.getBytes();
        for (int i = 0; i < (tmp.length / 2); i++) {
            ret[i] = uniteBytes(tmp[i * 2], tmp[i * 2 + 1]);
        }
        return ret;
    }

    /**
     * ASCII转 String
     *
     * @param value
     * @return
     */
    public static String asciiToString(String value) {
        StringBuffer sbu = new StringBuffer();
        String[] chars = value.split(",");
        for (int i = 0; i < chars.length; i++) {
            sbu.append((char) Integer.parseInt(chars[i]));
        }
        return sbu.toString();
    }

    /**
     * byte[] 转 ASCII
     *
     * @param value
     * @return
     */
    public static String asciiToString(byte value, byte value2, byte value3, byte value4) {
        String valstr = "";
        valstr = asciiToString(value + "") + asciiToString(value2 + "") + asciiToString(value3 + "") + asciiToString(value4 + "");
        return valstr;
    }

    /**
     * byte[] 转int
     *
     * @param src
     * @return
     */
    public static int bytesToInt(byte[] src) {
        ByteBuffer bb = ByteBuffer.wrap(src);
        int sxls = bb.getInt();
        return sxls;
    }


    /**
     * byte[] 转int
     *
     * @param val1
     * @param val2
     * @param val3
     * @param val4
     * @return
     */
    public static int byteToInt(byte val1, byte val2, byte val3, byte val4) {
        byte[] data = new byte[4];
        data[0] = val1;
        data[1] = val2;
        data[2] = val3;
        data[3] = val4;
        return bytesToInt(data);
    }

    /**
     * byte[] 转int
     * 2字节无符号整型
     *
     * @param bytes
     * @return
     */
    public static int bytestoInt(byte[] bytes) {
        ByteArrayInputStream in = new ByteArrayInputStream(bytes);
        int result = in.read();
        in.read();
        return result;
    }

    public static int bytestoInt(byte byte1, byte byte2) {
        byte[] data = new byte[2];
        data[0] = (byte) (0xff & byte1);
        data[1] = (byte) (0xff & byte2);
        return bytestoInt(data);
    }

    // 从byte数组的index处的连续4个字节获得一个float
    public static float getFloat(byte[] arr, int index) {
        return Float.intBitsToFloat(getInt(arr, index));
    }

    // 从byte数组的index处的连续4个字节获得一个int
    public static int getInt(byte[] arr, int index) {
        return (0xff000000 & (arr[index + 0] << 24)) |
                (0x00ff0000 & (arr[index + 1] << 16)) |
                (0x0000ff00 & (arr[index + 2] << 8)) |
                (0x000000ff & arr[index + 3]);
    }

    public static String getFloat(byte[] b) {
        DataInputStream dis = new DataInputStream(new ByteArrayInputStream(b));
        float f = 0;
        try {
            f = dis.readFloat();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            dis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return String.valueOf(f);
    }

    public static String getFloats(byte[] arr, int index) {
        byte[] data = new byte[4];
        data[0] = arr[index];
        data[1] = arr[index + 1];
        data[2] = arr[index + 2];
        data[3] = arr[index + 3];
        return getFloat(data);
    }

    /**
     * byte[]-2
     *
     * @param arr
     * @return byte[]-2
     */
    public static byte[] getBytelen(byte[] arr) {
        byte[] data = new byte[arr.length - 2];
        for (int i = 0; i < data.length; i++) {
            data[i] = arr[i];
        }
        return data;
    }

    /**
     * 计算CRC16校验码
     *
     * @param bytes
     * @return
     */
    public static String getCRC(byte[] bytes) {
        int CRC = 0x0000ffff;
        int POLYNOMIAL = 0x0000a001;

        int i, j;
        for (i = 0; i < bytes.length; i++) {
            CRC ^= ((int) bytes[i] & 0x000000ff);
            for (j = 0; j < 8; j++) {
                if ((CRC & 0x00000001) != 0) {
                    CRC >>= 1;
                    CRC ^= POLYNOMIAL;
                } else {
                    CRC >>= 1;
                }
            }
        }
        return Integer.toHexString(CRC);
    }

    private static String getCrc(byte[] data) {
        int high;
        int flag;

        // 16位寄存器，所有数位均为1
        int wcrc = 0xffff;
        for (int i = 0; i < data.length; i++) {
            // 16 位寄存器的高位字节
            high = wcrc >> 8;
            // 取被校验串的一个字节与 16 位寄存器的高位字节进行“异或”运算
            wcrc = high ^ data[i];

            for (int j = 0; j < 8; j++) {
                flag = wcrc & 0x0001;
                // 把这个 16 寄存器向右移一位
                wcrc = wcrc >> 1;
                // 若向右(标记位)移出的数位是 1,则生成多项式 1010 0000 0000 0001 和这个寄存器进行“异或”运算
                if (flag == 1)
                    wcrc ^= 0xa001;
            }
        }

        return Integer.toHexString(wcrc);
    }

//    public static void main(String[] args) {
//        byte[] data=select_sj((byte)0x01);
//        System.out.println("11111111111111111111111111111111111111111111111111111111111111111");
//        for (byte sss:data) {
//            System.out.print((sss & 0xFF)+" ");
//        }
//        System.out.println();
//        for (byte sss:data) {
//            System.out.print(sss+" ");
//        }
//    }

    public static byte[] select_sj(byte cjh) {
        byte[] data = new byte[8];
        data[0] = cjh;
        byte[] s = unsigned_short_2byte(2000);
        data[1] = 0x03;
        data[2] = s[0];
        data[3] = s[1];
        byte[] s2 = unsigned_short_2byte(63);
        data[4] = s2[0];
        data[5] = s2[1];
        byte[] a = CRC.getCRC6(data);
        data[6] = a[0];
        data[7] = a[1];
        return data;
    }

    // short整型转为byte类型的数组
    public static byte[] unsigned_short_2byte(int length) {
        byte[] targets = new byte[2];
        for (int i = 0; i < 2; i++) {
            int offset = (targets.length - 1 - i) * 8;
            targets[i] = (byte) ((length >>> offset) & 0xff);
        }

        return targets;
    }

    /**
     * 文件转为二进制数组
     *
     * @param file
     * @return
     */
    public static byte[] fileToBinArray(File file) {
        try {
            InputStream fis = new FileInputStream(file);
            byte[] bytes = FileCopyUtils.copyToByteArray(fis);
            return bytes;
        } catch (Exception ex) {
            throw new RuntimeException("transform file into bin Array 出错", ex);
        }
    }

    /**
     * 文件转为二进制字符串
     *
     * @param file
     * @return
     */
    public static String fileToBinStr(File file) {
        try {
            InputStream fis = new FileInputStream(file);
            byte[] bytes = FileCopyUtils.copyToByteArray(fis);
            return new String(bytes, "ISO-8859-1");
        } catch (Exception ex) {
            throw new RuntimeException("transform file into bin String 出错", ex);
        }
    }


    /**
     * 二进制字符串转文件
     *
     * @param bin
     * @param fileName
     * @param parentPath
     * @return
     */
    public static File binToFile(String bin, String fileName, String parentPath) {
        try {
            File fout = new File(parentPath, fileName);
            fout.createNewFile();
            byte[] bytes1 = bin.getBytes("ISO-8859-1");
            FileCopyUtils.copy(bytes1, fout);
            return fout;
        } catch (Exception ex) {
            throw new RuntimeException("transform bin into File 出错", ex);
        }
    }

    private static String intToHex(int n) {
        StringBuffer s = new StringBuffer();
        String a;
        char[] b = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
        while (n != 0) {
            s = s.append(b[n % 16]);
            n = n / 16;
        }
        a = s.reverse().toString();
        return a;
    }
}
